﻿using Pathfinding;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LFL_AstarPath : MonoBehaviour
{
    public Seeker seeker;
    // Start is called before the first frame update
    void Start()
    {
        if (AstarPath.active == null) return;
        ApplyGraphUpdateScene();
        //UpdateSpecifyGrid();
        // We can calculate multiple paths asynchronously
        //GetNearest();
        //Move();
    }

    /// <summary>
    /// 移动物体
    /// </summary>
    private void Move()
    {
        for (int i = 1; i < 10; i++)
        {
            //申请路径的起始与终点
            Path p = ABPath.Construct(transform.position, transform.position + new Vector3(0, i, 0), OnPathComplete);
            //开始寻找路径
            AstarPath.StartPath(p);
            //立刻获取寻找结果
            p.BlockUntilCalculated();

            Debug.Log(p.vectorPath.Count);
            for (int j = 0; j < p.vectorPath.Count; j++)
            {
                Debug.Log(p.vectorPath[j]);
            }
        }
    }

    private void OnPathComplete(Path p)
    {
        ////输出寻找到的路径
        //Debug.Log(p.vectorPath.Count);
        //for (int i = 0; i < p.vectorPath.Count; i++)
        //{
        //    Debug.Log(p.vectorPath[i]);
        //}
        //seeker.PostProcess(p);
    }


    /// <summary>
    /// 通过坐标寻找最近的节点
    /// </summary>
    private void GetNearest()
    {
        if (AstarPath.active == null) return;

        // Find the closest node to this GameObject's position
        GraphNode node = AstarPath.active.GetNearest(transform.position, NNConstraint.Default).node;

        if (node.Walkable)
        {
            Debug.Log((Vector3)node.position);
        }
        var graphToScan = AstarPath.active.data.gridGraph;
        AstarPath.active.Scan(graphToScan);
        var guo = new GraphUpdateObject(new Bounds());
    }


    /// <summary>
    /// 获取格子对格子进行 障碍点的设置
    /// </summary>
    public void UpdateSpecifyGrid()
    {
        AstarPath.active.AddWorkItem(new AstarWorkItem(ctx =>
        {
            var gg = AstarPath.active.data.gridGraph;
            for (int z = 0; z < gg.depth; z++)
            {
                for (int x = 0; x < gg.width; x++)
                {
                    var node = gg.GetNode(x, z);
                    // This example uses perlin noise to generate the map
                    node.Walkable = Mathf.PerlinNoise(x * 0.087f, z * 0.087f) > 0.4f;
                }
            }

            // Recalculate all grid connections
            // This is required because we have updated the walkability of some nodes
            gg.GetNodes(node => gg.CalculateConnections((GridNodeBase)node));

            // If you are only updating one or a few nodes you may want to use
            // gg.CalculateConnectionsForCellAndNeighbours only on those nodes instead for performance.
        }));
    }

    //整体节点方位更新方案
    GraphUpdateScene graphUpdateScene;
    public void ApplyGraphUpdateScene()
    {
        graphUpdateScene.Apply();
    }
}

public class MyGUO : GraphUpdateObject
{
    public Vector3 offset = Vector3.up;
    public override void Apply(GraphNode node)
    {
        // Keep the base functionality
        base.Apply(node);
        // The position of a node is an Int3, so we need to cast the offset
        node.position += (Int3)offset;
    }
}